package com.wzy.common.base.Youdao;

/**
 * 2 * @Author: wuzhengyu
 * 3 * @Date: 2021/4/23 18:05
 * 4
 */

import javax.websocket.ContainerProvider;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
import java.io.*;
import java.net.URI;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
import java.util.UUID;

public class StreamSpeechDemo {

    public Session session;

    //public static void main(String[] args) throws Exception {
    //
    //    String filePath = mp42wav("D:\\test.mp4_20210423_180032.mkv");;
    //    String from = "en";
    //    String to = "zh-CHS";
    //    String appKey = "1b08c7b23b409d2a";
    //    String appSecret = "kCpoup9tkqdudd1fPy0QI7W7VGGbodeZ";
    //    streamSpeech(appKey,appSecret,filePath, from, to);
    // }

    //String mp42wav(String sourcePath) {
    //    String webRoot = "C:\\Users\\wuzhengyu\\Desktop\\ffmpeg\\bin";
    //    Runtime run = null;
    //    run = Runtime.getRuntime();
    //    long start = System.currentTimeMillis();
    //    System.out.println(new File(webRoot).getAbsoluteFile());
    //    String outPath = "D:\\test\\out\\" + UUID.randomUUID() + ".wav";
    //    String cmd = new File(webRoot).getAbsoluteFile() + "\\ffmpeg.exe -i " + sourcePath + " -ar 16000 " + outPath;
    //    System.out.println(cmd);
    //    try {
    //        Process p = run.exec(cmd);
    //        p.getOutputStream().close();
    //        p.getInputStream().close();
    //        p.getErrorStream().close();
    //        p.waitFor();
    //        long end=System.currentTimeMillis();
    //        System.out.println(sourcePath+" convert success, costs:"+(end-start)+"ms");
    //    } catch (IOException | InterruptedException e) {
    //        e.printStackTrace();
    //    } finally {
    //        run.freeMemory();
    //    }
    //    return outPath;
    //}

    protected void start(String uri) {
        WebSocketContainer container = ContainerProvider.getWebSocketContainer();

        try {
            session = container.connectToServer(Websocket.class, URI.create(uri));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String doAsrWebSocketClient(String filePath, String uri, Integer step) {
        StreamSpeechDemo streamSpeechDemoWebSocketClientApp = new StreamSpeechDemo();
        streamSpeechDemoWebSocketClientApp.start(uri);
        try {
            InputStream inputStream = new FileInputStream(filePath);
            int read = 0;
            byte[] bytes = new byte[step];
            while ((read = inputStream.read(bytes)) != -1) {
                streamSpeechDemoWebSocketClientApp.session.getBasicRemote().sendBinary(ByteBuffer.wrap(bytes));
                Thread.sleep(200);
            }
            byte[] closebytes = "{\"end\": \"true\"}".getBytes();
            streamSpeechDemoWebSocketClientApp.session.getBasicRemote().sendBinary(ByteBuffer.wrap(closebytes));


        } catch (Exception e) {
            e.printStackTrace();
        }
        // 发送结束之后要做个处理
        System.out.println(Websocket.caption);
        StringBuilder sb = new StringBuilder();
        Websocket.caption.forEach(c -> {
            // 序号
            sb.append(Integer.parseInt(c.get("segId")) - 1).append("\n");
            // 时间片段
            SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
            String bg = format.format(Long.parseLong(c.get("bg")) - TimeZone.getDefault().getRawOffset());
            String ed = format.format(Long.parseLong(c.get("ed")) - TimeZone.getDefault().getRawOffset());
            sb.append(bg).append(" --> ").append(ed);
            sb.append("\n");
            // 英文原文
            sb.append(c.get("context"));
            sb.append("\n");
            // 中文翻译
            sb.append(c.get("tranContent"));
            sb.append("\n");
            sb.append("\n");
        });
        System.out.println(sb);
        return sb.toString();
        //saveAsFileWriter(sb.toString(),"D:\\test\\srt\\" + );
    }


    public static void saveAsFileWriter(String content, String filePath) {
        FileWriter fwriter = null;
        try {
            // true表示不覆盖原来的内容，而是加到文件的后面。若要覆盖原来的内容，直接省略这个参数就好
            fwriter = new FileWriter(filePath, true);
            fwriter.write(content);
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                fwriter.flush();
                fwriter.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    static String streamSpeech(String appKey, String appSecret, String filePath, String from, String to) throws NoSuchAlgorithmException {
        StreamSpeechDemo asrWebSocketClient = new StreamSpeechDemo();
        String nonce = UUID.randomUUID().toString();
        String curtime = String.valueOf(System.currentTimeMillis()/1000);
        String signStr = appKey + nonce +curtime + appSecret;
        String sign =  encrypt(signStr,null);

        String uri = "wss://openapi.youdao.com/stream_speech_trans?appKey="+appKey+"&salt="+nonce+"&curtime="+curtime+"&sign="+sign+"&version=v1&channel=1&format=wav&signType=v4&rate=16000&from=" + from + "&to=" + to + "&transPattern=stream";
        return asrWebSocketClient.doAsrWebSocketClient(filePath,uri, 6400);
    }

    /**
     * 获取MessageDigest的加密结果
     * @param strSrc
     * @param encName
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static String encrypt(String strSrc, String encName) throws NoSuchAlgorithmException {
        byte[] bt = strSrc.getBytes();
        if (encName == null || "".equals(encName)) {
            encName = "SHA-256";
        }
        MessageDigest md = MessageDigest.getInstance(encName);
        md.update(bt);
        // to HexString
        return bytes2Hex(md.digest());
    }
    public static String bytes2Hex(byte[] bts) {
        String des = "";
        String tmp;
        for (int i = 0; i < bts.length; i++) {
            tmp = (Integer.toHexString(bts[i] & 0xFF));
            if (tmp.length() == 1) {
                des += "0";
            }
            des += tmp;
        }
        return des;
    }
}
